package com.yunhe.option.service.data.impl;

import com.yunhe.option.domain.base.Area;
import com.yunhe.option.domain.data.GeneratePrice;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.PageParam;
import com.yunhe.option.repository.data.GeneratePriceRepository;
import com.yunhe.option.repository.data.impl.GeneratePriceDao;
import com.yunhe.option.service.base.AreaService;
import com.yunhe.option.service.data.GeneratePriceService;
import com.yunhe.common.util.QueryUtil;
import com.yunhe.common.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

//import com.yunhe.common.domain.data.Area;
//import com.yunhe.common.service.data.AreaService;

/**
 * 发电电价服务类实现
 * @author liuronglei
 */
@Service
public class GeneratePriceServiceImpl implements GeneratePriceService {

    @Autowired
    private GeneratePriceRepository generatePriceRepository;
    @Autowired
    private GeneratePriceDao generatePriceDao;
    @Autowired
    private AreaService areaService;


    private void processBeforeSave(GeneratePrice generatePrice)
            throws ArgumentErrorException, UniqueConstraintsException {
        //判断电价名称、地区是否为空
        if (StringUtil.isEmpty(generatePrice.getTitle())
                || generatePrice.getAreaList() == null) {
            throw new ArgumentErrorException("电价名称和地区不能为空");
        }
        //判断标题是否重复
        GeneratePrice priceByTitle = generatePriceRepository.findByTitle(generatePrice.getTitle());
        if (priceByTitle != null) {
            if (generatePrice.getId() == null|| priceByTitle.getId().longValue() != generatePrice.getId().longValue()) {
                throw new UniqueConstraintsException("该电价表标题已存在");
            }
        }
    }

    /**
     * 新增发电电价对象
     * @param generatePrice
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public GeneratePrice create(GeneratePrice generatePrice)
            throws ArgumentErrorException, UniqueConstraintsException {
        generatePrice.setId(null);
        List<Long> areaList = generatePrice.getAreaList();
        processBeforeSave(generatePrice);
        GeneratePrice newGP = generatePriceRepository.save(generatePrice);
        if (areaList != null && areaList.size() > 0) {
            Long areaId = areaList.get(areaList.size() - 1);
//            Area area = areaService.findByAreaId(areaId);
            Area area =  areaService.findById(areaId);
            if (area != null) {
                this.bindArea(newGP, area);
            }
        }
        return newGP;
    }

    /**
     * 根绝ID删除发电电价
     * @param gpId
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public void delete(Long gpId) {
        generatePriceRepository.deleteById(gpId);
    }

    /**
     * 更新发电电价对象（全部字段）
     * @param generatePrice
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public GeneratePrice update(GeneratePrice generatePrice) throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        boolean exists = generatePrice.getId() != null && generatePriceRepository.existsById(generatePrice.getId());
        if (!exists) {
            throw new ObjectNotFoundException("找不到ID为" + generatePrice.getId() + "的价格类型");
        }
        processBeforeSave(generatePrice);
        return generatePriceRepository.save(generatePrice);
    }

    /**
     * 更新发电电价对象（指定字段）
     * @param id
     * @param title
     * @param areaList
     * @param windPrice
     * @param pvPrice
     * @return
     * @throws ArgumentErrorException
     * @throws ObjectNotFoundException
     * @throws UniqueConstraintsException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public GeneratePrice update(Long id,
                                String title,
                                List<Long> areaList,
                                Double windPrice,
                                Double pvPrice)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException {
        GeneratePrice gp2 = this.findById(id).get();
        if (gp2 == null) {
            throw new ObjectNotFoundException("找不到ID为" + id + "的价格类型");
        }
        Optional.ofNullable(title).ifPresent(gp2::setTitle);
        Optional.ofNullable(areaList).ifPresent(gp2::setAreaList);
        Optional.ofNullable(windPrice).ifPresent(gp2::setWindPrice);
        Optional.ofNullable(pvPrice).ifPresent(gp2::setPvPrice);
        processBeforeSave(gp2);
        return generatePriceRepository.save(gp2);
    }

    /**
     * 根据条件查询发电电价
     * @param queryStr
     * @param pageParam
     * @return
     */
    @Transactional
    @Override
    public Iterable<GeneratePrice> search(String queryStr,
                                          Long stationId,
                                          PageParam pageParam) {
        if (stationId != null) {
            return generatePriceRepository.findByStationId(stationId);
        } else if (StringUtils.isNotEmpty(queryStr)) {
            int page = 0;
            int size = 0;
            Boolean needPage = false;
            if (QueryUtil.needPaging(pageParam)) {
                needPage = true;
                page = pageParam.getPage();
                size = pageParam.getSize();
            }
            if (page > 1) {
                page = page - 1;
            }
            List<String> sortList = pageParam.getSort();
            Iterable<GeneratePrice> generatePrices = generatePriceDao.getByQueryStr(queryStr, page, size, sortList);
            List<Long> idList = new ArrayList<>();
            for(GeneratePrice gp : generatePrices) {
                idList.add(gp.getId());
            }
            generatePrices = generatePriceDao.getInfo(idList);
            List<GeneratePrice> results = (List<GeneratePrice>)generatePrices;
            if (needPage) {
                Long totalCount = findTotalCount(queryStr);
                Pageable pageable = QueryUtil.getPageRequest(pageParam);
                return new PageImpl<>(results, pageable, totalCount);
            } else {
                return results;
            }
        }
        return null;
    }

    /**
     * 根据ID查找发电电价
     * @param id
     * @return
     */
    @Transactional
    @Override
    public Optional<GeneratePrice> findById(Long id) {
        return generatePriceRepository.findById(id);
    }

//    @Override
//    public GeneratePrice findByTitle(String title) {
//        return generatePriceRepository.findByTitle(title);
//    }

    /**
     * 返回符合条件的发电电价的总数
     * @param queryStr
     * @return
     */
    @Transactional
    @Override
    public Long findTotalCount(String queryStr) {
        String cypher = "match(g:GeneratePrice)-[:AREA_OF]->(a:Area), p=(m)-[r:HAS_CHILD*..2]->(a) where 1=1";
        if (StringUtils.isNotEmpty(queryStr)) {
            cypher ="where gp.title contains {queryStr} or gp.property contains {queryStr} or "
                    + "gp.province contains {queryStr} or gp.city contains {queryStr} or gp.district contains {queryStr}"
                    + " or v.title contains {queryStr} or d.title contains {queryStr} or n.title contains {queryStr} with s";
        }
        cypher = cypher + "return count(g) as count";
        List<Map<String, Object>> list = generatePriceDao.search(cypher);
        if (list.size() > 0) {
            return (long)(int)list.get(0).get("count");
        } else {
            return 0L;
        }
    }

    /**
     * 绑定发电电价地区
     * @param generatePrice
     * @param area
     */
    @Override
    @Transactional
    public void bindArea(GeneratePrice generatePrice, Area area) {
//        Area bandArea = generatePrice.getDistrict() != null ? generatePrice.getDistrict()
//                : generatePrice.getCity() != null ? generatePrice.getCity() : generatePrice.getProvince();
//        if (bandArea != null) {
//            generatePriceRepository.bindArea(generatePrice.getId(), bandArea.getId());
//        }
        generatePriceRepository.bindArea(generatePrice.getId(), area.getId());
    }

    /**
     * 绑定电站和电价
     * @param stationId
     * @param generatePriceId
     */
    @Override
    public void bindStation(Long stationId, Long generatePriceId) {
        generatePriceRepository.bindStation(stationId, generatePriceId);
    }
}
